#include "stdafx.h"
#include "RvalueReference.h"
#include "NamedMockData.h"

NamedMockData<char> generateOneInstance()
{
	NamedMockData<char> tmp;
	return tmp;

	// Bellow code seems optimized by compile
	// There is no any copy or move operator after return.
	// return NamedHugeData();
}

// It's a very important case to know the copy and move constructor semantic
void RValueReferenceAction(void)
{
	NamedMockData<char> d1;
	NamedMockData<char> d2 = std::move(d1);

	NamedMockData<char> d3 = static_cast<NamedMockData<char>&&>(d2);

	NamedMockData<char> d4 = generateOneInstance();

	// Bellow code means that std::move just cast the type from LValue to RValue
	NamedMockData<char>&& d5 = std::move(d4);
	NamedMockData<char>&& d6 = std::move(d5);

	d4.Print();

	NamedMockData<char>& tmp1 = d4;
	tmp1 = d4;

	NamedMockData<char>& tmp2 = d4;
	tmp2 = d4;
	tmp2.Print();
}

#include <vector>
#include <memory>
void RvalueStackScopeAction(void)
{
	std::vector<NamedMockData<int, 10000L>> v;

	v.push_back(NamedMockData<int, 10000L>());
	v.push_back(NamedMockData<int, 10000L>());

	v.insert(std::end(v) - 2, NamedMockData<int, 10000L>());
}

void RvalueWithSTLContainerAction(void)
{
	std::vector<std::unique_ptr<NamedMockData<long>>> v;

	v.push_back(std::unique_ptr<NamedMockData<long>>(new NamedMockData<long>));
	v.push_back(std::unique_ptr<NamedMockData<long>>(new NamedMockData<long>));
	v.push_back(std::unique_ptr<NamedMockData<long>>(new NamedMockData<long>));

	std::cout << "\n ::: Drop an element from back" << std::endl;
	v.pop_back();
	std::cout << " :::" << std::endl;

	v.insert(std::begin(v), std::unique_ptr<NamedMockData<long>>(new NamedMockData<long>));
}